package com.spring.proxy;

// 动态代理 模拟，AOP就是通过动态代理来实现的

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxy {
    // 传递目标对象
    private Object object;
    public DynamicProxy(Object object) {
        this.object = object;
    }

    // 返回代理对象
    public Object getProxy() {
        /*
             ClassLoader loader    参数一：加载动态生成代理类的类加载器
             Class<?>[] interfaces    参数二：目标对象实现的所有接口的class类型数组
             InvocationHandler h   参数三：设置代理对象实现目标对象方法的过程
        */
        ClassLoader loader = object.getClass().getClassLoader(); // 参数一
        Class<?>[] interfaces = object.getClass().getInterfaces(); // 参数二
        InvocationHandler h = new InvocationHandler() {   // 参数三，这是一个接口，需要实现它里面的 invoke 方法
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                /*
                     Object proxy 代理对象
                     Method method 需要重写目标对象的方法
                     Object[] args 第二个参数 method 方法里面的参数
                */
                // 代理
                System.out.println("动态代理，之前。。。。。。");
                // 核心业务，调用目标方法
                Object result = method.invoke(object, args);
                // 代理
                System.out.println("动态代理，之后。。。。。。");
                return result;
            }
        };
        return Proxy.newProxyInstance(loader,interfaces,h); // 通过 Proxy.newProxyInstance() 实现动态代理
    }

    // 测试
    public static void main(String[] args) {
        // 传递需要被代理的对象
        DynamicProxy dynamicProxy = new DynamicProxy(new CalculatorImpl());
        // 得到代理对象
        Calculator calculator = (Calculator) dynamicProxy.getProxy();
        // 调用方法
        calculator.add(1,2);
    }

}
